#!/bin/bash

# 脚本名称: modify_value_in_files.sh
# 功能: 在指定目录结构下，修改文件值 或 还原备份文件。
# 作者: 资深技术专家
# 日期: 2025-09-09
# 版本: 4.0 (支持还原 + 参数化目录结构 + 无交互 + 查看 + 确认)

###使用方法###
##目录层级  aa/bb*   
# 修改值
#./modify_value_in_files.sh aa 'bb*' config.txt 'debug=false' 'debug=true'
# 还原被修改的文件
#./modify_value_in_files.sh -r aa 'bb*' config.txt

show_usage() {
    echo "Usage:"
    echo "  修改模式: $0 <base_dir> <subdir_pattern> <filename> <old_value> <new_value>"
    echo "  还原模式: $0 -r <base_dir> <subdir_pattern> <filename>"
    echo ""
    echo "Example (修改):"
    echo "  $0 aa 'bb*' config.txt 'port=8080' 'port=9090'"
    echo ""
    echo "Example (还原):"
    echo "  $0 -r aa 'bb*' config.txt"
    echo ""
    echo "说明:"
    echo "  -r, --restore : 启用还原模式，将 .bak 备份文件恢复为原文件。"
    echo "  <base_dir>    : 基础目录（如 'aa'）"
    echo "  <subdir_pattern>: 子目录匹配模式（如 'bb*'，支持通配符）"
    echo "  <filename>    : 文件名（修改模式下为目标文件；还原模式下为要还原的文件名）"
    echo "  <old_value>   : (仅修改模式) 要被替换的旧字符串"
    echo "  <new_value>   : (仅修改模式) 替换后的新字符串"
}

# === 解析还原选项 ===
RESTORE_MODE=false
while [[ $# -gt 0 ]]; do
    case $1 in
        -r|--restore)
            RESTORE_MODE=true
            shift
            ;;
        *)
            break
            ;;
    esac
done

# === 参数校验 ===
if [ "$RESTORE_MODE" = true ]; then
    if [ $# -ne 3 ]; then
        echo "❌ 错误：还原模式下需要 3 个参数。"
        show_usage
        exit 1
    fi
    BASE_DIR="$1"
    SUBDIR_PATTERN="$2"
    TARGET_FILENAME="$3"
else
    if [ $# -ne 5 ]; then
        echo "❌ 错误：修改模式下需要 5 个参数。"
        show_usage
        exit 1
    fi
    BASE_DIR="$1"
    SUBDIR_PATTERN="$2"
    TARGET_FILENAME="$3"
    OLD_VALUE="$4"
    NEW_VALUE="$5"
fi

# 校验基础目录
if [ ! -d "$BASE_DIR" ]; then
    echo "❌ 错误：基础目录 '$BASE_DIR' 不存在或不是目录。"
    exit 1
fi

# === 根据模式执行不同操作 ===
if [ "$RESTORE_MODE" = true ]; then
    echo "🔄【还原模式】即将还原文件: $TARGET_FILENAME"
else
    # 转义函数，用于安全处理 sed 中的特殊字符
    escape_sed_pattern() {
        echo "$1" | sed -e 's/[\/&]/\\&/g' -e 's/[]\/$*.^|[]/\\&/g'
    }
    ESCAPED_OLD=$(escape_sed_pattern "$OLD_VALUE")
    ESCAPED_NEW=$(escape_sed_pattern "$NEW_VALUE")

    echo "✏️ 【修改模式】即将替换: '$OLD_VALUE' -> '$NEW_VALUE'"
fi

echo "========================================"
echo "【操作概览】"
echo "  模式:           $([ "$RESTORE_MODE" = true ] && echo "还原" || echo "修改")"
echo "  基础目录:       $BASE_DIR"
echo "  子目录模式:     $SUBDIR_PATTERN"
echo "  目标文件名:     $TARGET_FILENAME"
[ "$RESTORE_MODE" = false ] && {
    echo "  旧值:           $OLD_VALUE"
    echo "  新值:           $NEW_VALUE"
}
echo "========================================"

# === 查找匹配的子目录 ===
shopt -s nullglob
SUBDIRS=("$BASE_DIR"/$SUBDIR_PATTERN)

if [ ${#SUBDIRS[@]} -eq 0 ]; then
    echo "⚠️  警告：未找到匹配子目录 '$SUBDIR_PATTERN' 在 '$BASE_DIR' 下。"
    exit 0
fi

# === 核心处理循环 ===
for dir in "${SUBDIRS[@]}"; do
    if [ ! -d "$dir" ]; then
        continue
    fi

    TARGET_FILE="$dir/$TARGET_FILENAME"
    BACKUP_FILE="$TARGET_FILE.bak"

    if [ "$RESTORE_MODE" = true ]; then
        # ========== 还原模式 ==========
        if [ -f "$BACKUP_FILE" ]; then
            echo -e "\n>>> 还原文件: $TARGET_FILE"

            # --- 查看项：还原前 ---
            echo "【还原前 - 当前文件信息】"
            if [ -f "$TARGET_FILE" ]; then
                ls -l "$TARGET_FILE"
                echo "当前内容预览 (前3行):"
                head -n 3 "$TARGET_FILE"
            else
                echo "  [INFO] 目标文件不存在，将从备份创建。"
            fi

            echo "【执行还原】"
            cp "$BACKUP_FILE" "$TARGET_FILE" && {
                echo "  ✅ 还原成功。"
                # 删除备份文件（可选，根据需求决定是否保留）
                # rm "$BACKUP_FILE" && echo "  🗑️  备份文件已删除。"

                # --- 修改确认项：还原后 ---
                echo "【还原后 - 当前文件信息】"
                ls -l "$TARGET_FILE"
                echo "当前内容预览 (前3行):"
                head -n 3 "$TARGET_FILE"
                echo "  ✅ [SUCCESS] 还原操作已确认完成。"
            } || {
                echo "  ❌ [ERROR] 还原失败。"
            }
        else
            echo "  ⚠️  [WARNING] 在目录 $dir 中未找到备份文件: $BACKUP_FILE"
        fi

    else
        # ========== 修改模式 ==========
        if [ -f "$TARGET_FILE" ]; then
            echo -e "\n>>> 处理文件: $TARGET_FILE"

            # --- 查看项：修改前 ---
            echo "【修改前】"
            MATCHED_LINES_BEFORE=$(grep -n "$OLD_VALUE" "$TARGET_FILE" 2>/dev/null)
            if [ -n "$MATCHED_LINES_BEFORE" ]; then
                echo "$MATCHED_LINES_BEFORE" | sed 's/^/  行 /'
            else
                echo "  [INFO] 未找到包含 '$OLD_VALUE' 的行。"
            fi

            # 创建备份
            echo "【执行备份】"
            cp "$TARGET_FILE" "$BACKUP_FILE" && echo "  ✅ 备份成功: $BACKUP_FILE" || {
                echo "  ❌ [ERROR] 备份失败！跳过此文件。"
                continue
            }

            # 执行替换
            echo "【执行替换】"
            sed -i "s/$ESCAPED_OLD/$ESCAPED_NEW/g" "$TARGET_FILE"
            if [ $? -eq 0 ]; then
                echo "  ✅ 替换命令执行成功。"

                # --- 修改确认项：修改后 ---
                echo "【修改后】"
                MATCHED_LINES_AFTER=$(grep -n "$NEW_VALUE" "$TARGET_FILE" 2>/dev/null)
                if [ -n "$MATCHED_LINES_AFTER" ]; then
                    echo "$MATCHED_LINES_AFTER" | sed 's/^/  行 /'
                    echo "  ✅ [SUCCESS] 修改已确认生效。"
                else
                    if [ -n "$MATCHED_LINES_BEFORE" ]; then
                        echo "  ⚠️  [WARNING] 未找到新值，但之前有旧值，替换可能未生效。"
                    else
                        echo "  ℹ️  [INFO] 无匹配行，无需替换。"
                    fi
                fi
            else
                echo "  ❌ [ERROR] 替换操作失败。请检查文件权限或内容格式。"
            fi

        else
            echo "  ⚠️  [WARNING] 在目录 $dir 中未找到文件: $TARGET_FILENAME"
        fi
    fi
done

echo -e "\n✅ 所有操作已完成。"
